<template>
  <view class="gi-tag" :class="getClass" :style="getStyle" @click="onClick">
    <view v-if="slot.icon" class="gi-tag__icon">
      <slot name="icon"></slot>
    </view>
    <slot></slot>
  </view>
</template>

<script lang="ts" setup>
import { computed, type CSSProperties, useSlots } from 'vue'

const props = withDefaults(defineProps<Props>(), {
  type: 'light',
  status: '',
  size: 'medium',
  shape: 'square',
  _class: '',
})

const emit = defineEmits<{
  (e: 'click'): void
}>()

const slot = useSlots()

const baseColorObj: Record<string, string> = {
  red: '#FF0000 ',
  orangered: '#f77234',
  orange: '#ff7d00',
  gold: '#f7ba1e',
  lime: '#9fdb1d',
  green: '#00b42a',
  cyan: '#14c9c9',
  blue: '#3491fa',
  purple: '#722ed1',
  pink: '#f5319d',
  gray: '#86909c',
}

type BaseColor = keyof typeof baseColorObj

interface Props {
  type?: 'light' | 'dark' | 'text' | 'outline'
  status?: 'primary' | 'success' | 'warning' | 'danger' | ''
  color?: BaseColor | string
  size?: 'medium' | 'small' | 'large'
  shape?: 'round' | 'square'
  _class?: string
  _style?: CSSPerspective
}

function onClick() {
  emit('click')
}

const getClass = computed(() => {
  const arr = []
  if (props.size) {
    arr.push(`gi-tag__size--${props.size}`)
  }
  if (props.shape) {
    arr.push(`gi-tag__shape--${props.shape}`)
  }
  if (props.type) {
    arr.push(`gi-tag__type--${props.type}`)
  }
  if (props.status && !props.color) {
    arr.push(`gi-tag__status--${props.status}`)
  }
  if (props._class) {
    arr.push(props._class)
  }
  return arr.join(' ')
})

function hexToRgb(hex: string) {
  if (hex.includes('#')) {
    hex = hex.slice(1)
  }
  const r = Number.parseInt(hex.slice(0, 2), 16)
  const g = Number.parseInt(hex.slice(2, 4), 16)
  const b = Number.parseInt(hex.slice(4, 6), 16)
  return { r, g, b }
}

const getStyle = computed(() => {
  const obj: CSSProperties = {}
  if (props.color) {
    const color = baseColorObj[props.color] || props.color
    const { r, g, b } = hexToRgb(color)
    if (props.type === 'light') {
      obj.color = color
      obj.backgroundColor = `rgba(${r}, ${g}, ${b}, 0.1)`
    }
    if (props.type === 'dark') {
      obj.color = '#fff'
      obj.backgroundColor = color
    }
    if (props.type === 'text') {
      obj.color = color
      obj.backgroundColor = 'transparent'
    }
    if (props.type === 'outline') {
      obj.color = color
      obj.backgroundColor = 'transparent'
      obj.borderColor = color
    }
  }
  return { ...obj, ...props._style }
})
</script>

<style lang="scss" scoped>
$color-theme: #0088fe; // 主题色
$color-primary: #0088fe;
$color-success: #00a85a;
$color-warning: #f88615;
$color-danger: #ff0000;
$color-default: #354ba1;

.gi-tag {
  box-sizing: border-box;
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  height: 20px;
  padding: 0 5px;
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;

  .gi-tag__icon {
    width: 12px;
    height: 12px;
    margin-right: 10px;
  }

  &.gi-tag__size--small {
    height: 17px;
    font-size: 10px;

    .gi-tag__icon {
      width: 10px;
      height: 10px;
    }

    &.gi-tag__type--text {
      font-size: 12px;
    }
  }

  &.gi-tag__size--large {
    height: 22px;
    font-size: 13px;

    .gi-tag__icon {
      width: 14px;
      height: 14px;
    }
  }

  &.gi-tag__shape--round {
    border-radius: 100px;
  }

  &.gi-tag__shape--square {
    border-radius: 2px;
  }

  &.gi-tag__type--light {
    color: $color-default;
    background-color: rgba($color: $color-default, $alpha: 0.1);

    &.gi-tag__status--primary {
      color: $color-primary;
      background-color: rgba($color: $color-primary, $alpha: 0.1);
    }

    &.gi-tag__status--success {
      color: $color-success;
      background-color: rgba($color: $color-success, $alpha: 0.1);
    }

    &.gi-tag__status--warning {
      color: $color-warning;
      background-color: rgba($color: $color-warning, $alpha: 0.1);
    }

    &.gi-tag__status--danger {
      color: $color-danger;
      background-color: rgba($color: $color-danger, $alpha: 0.1);
    }
  }

  &.gi-tag__type--dark {
    color: #fff;
    background-color: $color-default;

    &.gi-tag__status--primary {
      background-color: $color-primary;
    }

    &.gi-tag__status--success {
      background-color: $color-success;
    }

    &.gi-tag__status--warning {
      background-color: $color-warning;
    }

    &.gi-tag__status--danger {
      background-color: $color-danger;
    }
  }

  &.gi-tag__type--text {
    padding: 0;
    font-size: 14px;
    color: $color-default;
    &.gi-tag__status--primary {
      color: $color-primary;
    }

    &.gi-tag__status--success {
      color: $color-success;
    }

    &.gi-tag__status--warning {
      color: $color-warning;
    }

    &.gi-tag__status--danger {
      color: $color-danger;
    }
  }

  &.gi-tag__type--outline {
    color: $color-default;
    border-color: $color-default;
    border-style: solid;
    border-width: 0.8px;

    &.gi-tag__status--primary {
      color: $color-primary;
      border-color: $color-primary;
    }

    &.gi-tag__status--success {
      color: $color-success;
      border-color: $color-success;
    }

    &.gi-tag__status--warning {
      color: $color-warning;
      border-color: $color-warning;
    }

    &.gi-tag__status--danger {
      color: $color-danger;
      border-color: $color-danger;
    }
  }
}
</style>
